<!--
* @author luguoxiang
* @date 2021-09-07
* 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
-->
<template>
  <slot name="custom" :files="files" :choose="choose" :upload="upload" :remove="remove">
    <!--  img 样式  -->
    <div v-if="type === 'img'" :key="key" class="lg-upload lg-upload-img">
      <slot name="files" :files="files">
        <div v-for="(x, i) in files" :key="x.id" class="lg-upload-item" :class="`lg-upload-${x.status || 0}`">
          <img
            class="lg-upload-file"
            :src="getFileAccessAuthUrl(x.url, 's')"
            onload="this.style.display = ''"
            onerror="this.style.display == 'none'"
            @click="clickFile(x, i)"
          />
          <div v-if="!disabled" class="lg-upload-remove" @click="remove(i)">
            <close-icon />
          </div>
        </div>
      </slot>
      <div v-if="showTrigger" class="lg-upload-item">
        <div class="lg-upload-trigger" @click="choose">
          <slot>
            <div style="text-align: center">
              <span style="font-size: 32px; font-weight: 100">+</span>
              <div style="color: var(--app-color-placeholder)">选择图片</div>
            </div>
          </slot>
        </div>
      </div>
    </div>
    <!--  table 样式  -->
    <div v-else-if="type === 'table'" :key="key" class="lg-upload lg-upload-table">
      <div v-if="showTrigger" class="lg-upload-trigger">
        <span @click="choose">
          <slot>
            <t-button theme="primary">选择文件</t-button>
          </slot>
        </span>
        <span v-if="manual" @click="upload">
          <slot name="upload">
            <t-button theme="success">点击上传</t-button>
          </slot>
        </span>
      </div>
      <slot name="files" :files="files">
        <table class="lg-upload-files">
          <thead>
          <tr>
            <th>文件名</th>
            <th style="width: 120px">文件大小</th>
            <th style="width: 120px">状态</th>
            <th v-if="!disabled" style="width: 80px; text-align: center">操作</th>
          </tr>
          </thead>
          <tbody>
          <tr v-for="(x, i) in files" :key="x.id" class="lg-upload-item" :class="`lg-upload-${x.status || 0}`">
            <td class="t-upload__file-name">
                <span class="lg-upload-file" @click="clickFile(x, i)">
                  {{ x.name }}
                </span>
            </td>
            <td>{{ sizeFormat(x.size) }}</td>
            <td>
              <div class="t-upload__flow-status">
                <template v-if="x.status === 1">
                  <time-icon />
                  <span class="lg-ellipsis">等待上传</span>
                </template>
                <template v-else-if="x.status === 2">
                  <loading-icon />
                  <span class="lg-ellipsis">{{ x.percent }}%</span>
                </template>
                <template v-else-if="x.status === 3">
                  <error-circle-icon />
                  <span class="lg-ellipsis-1 t-upload__file-flow-fail">上传失败</span>
                </template>
                <template v-else>
                  <check-circle-icon />
                  <span class="lg-ellipsis-1">上传成功</span>
                </template>
              </div>
            </td>
            <td v-if="!disabled">
              <button
                class="t-button t-button--variant-text t-button--theme-primary t-upload__delete"
                type="button"
                @click="remove(i)"
              >
                <span class="t-button__text">删除</span>
              </button>
            </td>
          </tr>
          </tbody>
        </table>
      </slot>
    </div>
    <!--  list 样式  -->
    <div v-else :key="key" class="lg-upload lg-upload-list">
      <div v-if="showTrigger" class="lg-upload-trigger">
        <span @click="choose">
          <slot>
            <t-button theme="primary">选择文件</t-button>
          </slot>
        </span>
        <span v-if="manual" @click="upload">
          <slot name="upload">
            <t-button theme="success">点击上传</t-button>
          </slot>
        </span>
      </div>
      <slot name="files" :files="files">
        <div class="lg-upload-files">
          <div v-for="(x, i) in files" :key="x.id" class="lg-upload-item" :class="`lg-upload-${x.status || 0}`">
            <div class="lg-upload-file" @click="clickFile(x, i)">
              {{ x.name }}
            </div>
            <div class="lg-upload-ext">
              <template v-if="x.status === 2">
                <loading-icon />
                <span class="lg-upload-percent">{{ x.percent }}%</span>
              </template>
              <template v-else>
                <time-icon v-if="x.status === 1" />
                <error-circle-icon v-else-if="x.status === 3" />
                <close-icon v-if="!disabled" class="lg-upload-remove" @click="removeFile(i)" />
              </template>
            </div>
          </div>
        </div>
      </slot>
    </div>
  </slot>
  <lg-file-viewer ref="viewerRef" />
</template>

<script lang="ts" setup>
import './index.less';
import { computed, ref, watch } from 'vue';
import { CheckCircleIcon, CloseIcon, ErrorCircleIcon, LoadingIcon, TimeIcon } from 'tdesign-icons-vue-next';
import { getFileAccessAuthUrl, nextId, sizeFormat } from '@/soar';
import { LgUploadProps } from '../types';
import LgFileViewer from '../LgFileViewer/index.vue';
import { LgFile, useUploader, UseUploaderOptions } from '@/soar/hooks/upload';

interface Props extends UseUploaderOptions {
  modelValue?: any;
  type?: LgUploadProps['type'];
  disabled?: boolean;
  fixedTrigger?: boolean;
  valueType?: LgUploadProps['valueType'];
  accept?: string;
  count?: number | string;
  size?: number | string;
  manual?: boolean;
}

const props = defineProps<Props>();
const emits = defineEmits(['update:modelValue', 'change']);

const key = nextId();
const viewerRef = ref();

/**
 * 点击文件
 * @param file
 * @param index
 */
function clickFile(file: LgFile, index: number) {
  viewerRef.value.open({ files: files.value, index });
}

const showTrigger = computed(() => {
  if (props.disabled) {
    return false;
  }
  if (props.fixedTrigger) {
    return true;
  }
  const count = (props.valueType === 'url' || props.valueType === 'info') ? 1 : (props.count || Infinity)
  return files.value.length < count;
});

const { files, upload, choose, remove, updateValue } = useUploader(props, (value: any) => {
  emits('update:modelValue', value);
  emits('change', value);
});

watch(() => props.modelValue, updateValue, { immediate: true, deep: true });

function removeFile(e: any) {
  if (props.disabled) {
    return;
  }
  remove(e);
}

defineExpose({
  upload,
  choose,
  remove,
});
</script>
<script lang="ts">
export default {
  name: 'LgUpload',
};
</script>
